use Time::Local;

my $file = $ARGV[0];
$argc = @_;
#print "number is $temp";
if ($argc == 0){
	open INPUT, "<./output/AllLostPackets.dat" or die "cannot open ./output/AllLostPackets.dat\n";
}
else {
	open INPUT, "<$file" or die "cannot open $file";
}

$MINNODE=0;
$MAXNODE=1300;
$MIN_SEQ = 0;
$MAX_SEQ = 65535;
$MAX_TIME = hex("ffffffff");
$NORM_MIN_SEQ = 0; #nomorlized seq;
$NORM_MAX_SEQ = $MAX_SEQ - $MIN_SEQ;
#$AHEAD_BUFFER_SIZE = 5;
$CYCLE_LENGTH = 30*60*1024; #cycle length 30 min;
$MAX_ERROR = 15; #maximum error;

$START_YEAR = 2013;
$START_MONTH = 1;
$START_DATE = 9;
$START_HOUR = 0;
$START_MIN = 0;
$START_SEC = 0;
$START_MS = 0;
$START_TIME_STR = "$START_YEAR:$START_MONTH:$START_DATE:$START_HOUR:$START_MIN:$START_SEC:$START_MS";

$MS_PER_SEC = 1024;
$MS_PER_MIN = $MS_PER_SEC * 60;
$MS_PER_HOUR = $MS_PER_MIN * 60;
$MS_PER_DATE = $MS_PER_HOUR * 24;
$MS_PER_YEAR = $MS_PER_DATE*365;
$MS_PER_MONTH = $MS_PER_DATE*30;

@allids = ();
@alltypes = ();
@allseqs = ();
@alltime1 = ();
@alltime2 = ();
@alltime1ms = ();
@alltime2ms = ();

$lostPacketTimeFile = "AllLostPacketsTime.dat";
$lostPacketTimeFile2 = "AllLostPacketsTimeMat.dat";
open LOSTPACKETTIME, ">./output/$lostPacketTimeFile" or die "cannot open $lostPacketTimeFile\n";
open LOSTPACKETTIME2, ">./output/$lostPacketTimeFile2" or die "cannot open $lostPacketTimeFile2\n";

$lostNum = 0;
%lostpacket2time = ();
%idtypeseq2time = ();
%idtypeseq2endtime = ();
while($line = <INPUT>){
	chomp $line;
	#print "^^^$line\n";
	@rs = split(/\t/, $line);
	#print "***@rs \n";
	$allids[$lostNum] = $rs[0];
	$alltypes[$lostNum] = hex($rs[1]);
	$allseqs[$lostNum] = $rs[2];
	$alltime1[$lostNum] = $rs[3];
	$alltime2[$lostNum] = $rs[4];
	if ($lostNum == 0){
		&GetStartTime($alltime1[$lostNum]);
	}
	$tempBeginLostSeq = $allseqs[$lostNum];
	#totally $cycleDiff - 1 lost packets.
	$tempPacketLostTime = -1;
	$tempid = $allids[$lostNum];
	$temptype = $alltypes[$lostNum];
	$tempseq = $allseqs[$lostNum];

	if (!exists $idtypeseq2time{$tempid}{$temptype}{$tempseq}) {
		$idtypeseq2time{$tempid}{$temptype} = ();
		$idtypeseq2endtime{$tempid}{$temptype} = ();
	}elsif(exists $idtypeseq2endtime{$tempid}{$temptype}{$tempseq} 
		   && $idtypeseq2endtime{$tempid}{$temptype}{$tempseq} eq $alltime2[$lostNum]){#ignore those id type seqs that are previously considered...
		  # print "ignore packet at $alltime2[$lostNum]==$idtypeseq2endtime{$tempid}{$temptype}{$tempseq}\n";
		next;
	}
	#print "cyclediff:$cycleDiff:\n";
	
	$totalms1 = &Time2Ms($alltime1[$lostNum]);
	$totalms2 = &Time2Ms($alltime2[$lostNum]);
	
	$totalmsDiff = $totalms2 - $totalms1;
	$cycleDiff = $totalmsDiff / $CYCLE_LENGTH;
	$cycleDiff = int($cycleDiff + 0.2);
	if ($cycleDiff > 1){
		print LOSTPACKETTIME2 "$allids[$lostNum]\t$alltypes[$lostNum]\t$allseqs[$lostNum]\t$totalms1\n";
	}else{
		print "++++++++++++cyclediff:$cycleDiff: $tempid $temptype $tempseq\n";
	}

	for ($tempi = 1;$tempi < $cycleDiff; ++$tempi){
		$tempBeginLostSeq = $allseqs[$lostNum] + $tempi - 1;
		if (exists $idtypeseq2time{$tempid}{$temptype}{$tempBeginLostSeq} && $idtypeseq2endtime{$tempid}{$temptype}{$tempseq} eq $alltime2[$lostNum]){
			last;
		}
		#print "seq:$tempBeginLostSeq \n";
		if (exists $idtypeseq2time{$tempid}{$temptype}{$tempBeginLostSeq - 1})
		{
			$tempPacketLostTime = $idtypeseq2time{$tempid}{$temptype}{$tempBeginLostSeq - 1} + $CYCLE_LENGTH;
		}else{
			$tempPacketLostTime = $tempi * $CYCLE_LENGTH + $totalms1;
		}
		
		$idtypeseq2time{$tempid}{$temptype}{$tempBeginLostSeq} = $tempPacketLostTime;
		$idtypeseq2endtime{$tempid}{$temptype}{$tempBeginLostSeq} = $alltime2[$lostNum];
		#print "$idtypeseq2endtime{$tempid}{$temptype}{$tempBeginLostSeq} = $alltime2[$lostNum]\n";
		$lostpacketFormattedTime = &Ms2Time($tempPacketLostTime, $START_TIME_STR);
		print LOSTPACKETTIME "$allids[$lostNum]\t$alltypes[$lostNum]\t$tempBeginLostSeq\t$tempPacketLostTime\t$alltime1[$lostNum]\t$alltime2[$lostNum]\t$lostpacketFormattedTime\n";
		#print "lost packet: $allids[$lostNum] $alltypes[$lostNum] $tempBeginLostSeq $tempPacketLostTime $alltime1[$lostNum] $alltime2[$lostNum] $lostpacketFormattedTime\n";
		#print LOSTPACKETTIME2 "$allids[$lostNum]\t$alltypes[$lostNum]\t$tempBeginLostSeq\t$tempPacketLostTime\n";
	}
	$lostNum++;
}

close LOSTPACKETTIME;
close LOSTPACKETTIME2;

sub Time2Ms{
	$templine = shift;
	chomp $templine;
	@temprs = split(/:/, $templine);
	$tempyear = $temprs[0] - $START_YEAR;
	$tempmonth = $temprs[1] - $START_MONTH;
	$tempdate = $temprs[2] - $START_DATE;
	$temphour = $temprs[3] - $START_HOUR;
	$tempmin = $temprs[4] - $START_MIN;
	$tempsec = $temprs[5] - $START_SEC;
	$tempms = $temprs[6] - $START_MS;

	$temptotalms = $tempdate * $MS_PER_DATE + $temphour * $MS_PER_HOUR + $tempmin * $MS_PER_MIN + $tempsec * $MS_PER_SEC +$tempms;
	#print "+++@temprs[0..6] \n";
	#print "---$tempyear $tempmonth $tempdate $temphour $tempmin $tempsec $tempms $temptotalms \n";
	#print ">>>$START_YEAR:$START_MONTH:$START_DATE:$START_HOUR:$START_MIN:$START_SEC:$START_MS";
	return $temptotalms;
}

sub Time2S{
	$templine = shift;
	chomp $templine;
	@temprs = split(/:/, $templine);
	$tempyear = $temprs[0];# - $START_YEAR;
	$tempmonth = $temprs[1];# - $START_MONTH;
	$tempdate = $temprs[2];# - $START_DATE;
	$temphour = $temprs[3];# - $START_HOUR;
	$tempmin = $temprs[4];# - $START_MIN;
	$tempsec = $temprs[5];# - $START_SEC;
	$tempms = $temprs[6];# - $START_MS;
	$resulttime = timelocal($tempsec, $tempmin, $temphour, $tempdate, $tempmonth, $tempyear);
	return $resulttime;
}

sub S2Time{
	$temptotalS = shift;
	$tempStartTime = shift;
	($tempsec,$tempmin,$temphour,$tempdate,$tempmonth,$tempyear,$wday,$yday,$isdst)  = localtime($temptotalS);
	$tempyear = $tempyear + 1900;
	return "$tempyear:$tempmonth:$tempdate:$temphour:$tempmin:$tempsec:0";
}

sub Ms2Time{
	$temptotalMs = shift;
	$tempStartTime = shift;
	chomp $tempStartTime;
	@temprs = split(/:/, $tempStartTime);
	$tempyear = $temprs[0];
	$tempmonth = $temprs[1];
	$tempdate = $temprs[2];
	$temphour = $temprs[3];
	$tempmin = $temprs[4];
	$tempsec = $temprs[5];
	$tempms = $temprs[6];
	
	
	$tempyear =  $tempyear;
	$tempmonth = $tempmonth;
	$tempdate = $tempdate + int($temptotalMs / $MS_PER_DATE);
	$temptotalMs = $temptotalMs%$MS_PER_DATE;
	$temphour = $temphour + int($temptotalMs /$MS_PER_HOUR);
	$temptotalMs = $temptotalMs % $MS_PER_HOUR;
	$tempmin = $tempmin + int($temptotalMs / $MS_PER_MIN);
	$temptotalMs = $temptotalMs % $MS_PER_MIN;
	$tempsec = $tempsec + int($temptotalMs / $MS_PER_SEC);
	$temptotalMs = $temptotalMs % $MS_PER_SEC;
	$tempms = $tempms + $temptotalMs;
	
	return "$tempyear:$tempmonth:$tempdate:$temphour:$tempmin:$tempsec:$tempms";

}

sub GetStartTime
{
	$temptime = shift;
	chomp $temptime;
	#print "++++++++++++++$templine\n";
	@temprs = split(/:/, $temptime);
	$START_YEAR = $temprs[0];
	$START_MONTH = $temprs[1];
	$START_DATE = $temprs[2];
	$START_TIME_STR = "$START_YEAR:$START_MONTH:$START_DATE:$START_HOUR:$START_MIN:$START_SEC:$START_MS";

	#$START_HOUR = $temprs[3];
}